var _global = require('global/global.js');
var _vec3f = require('core/glm.js').vec3f;

var _Constant = require('scenes/game/constant.js');

var _Status = require('./slotstatus.js');
var SLOT_BLOCK = _Status.SLOT_BLOCK;
var SLOT_OVER = _Status.SLOT_OVER;// over an empty cell
var SLOT_MERGE = _Status.SLOT_MERGE;// will merge after movement

var ROW_COUNT = 4, COL_COUNT = 4;

var MOVE_LEFT = 0;
var MOVE_TOP = 1;
var MOVE_RIGHT = 2;
var MOVE_BOTTOM = 3;
var MOVE_DIRECTIONS = 4;

var _Utility = require('scenes/utility.js');

// ==========================
// Slot
// ==========================
function Slot(index) {
    this.mIndex = index;
    this.mPredict = new Array(MOVE_DIRECTIONS);

    var col = index % COL_COUNT;
    var row = (index - col ) / ROW_COUNT;
    this.mPosition = new _vec3f(col + 0.5, ROW_COUNT - row - 0.5);
    this.mPosition.mul(_Constant.slotSize);

    this.mCell = null;
}
Slot.prototype.getIndex = function () {
    return this.mIndex;
};
/**
 * @param previous block
 */
Slot.prototype.checkPredict = function (previous, state) {
    // empty slot does not move
    if (this.isEmpty()) {
        return SLOT_BLOCK;
    }
    // move over an empty slot
    if (previous.isEmpty()) {
        return SLOT_OVER;
    }
    // if previous is not empty, and blocked
    if (state == SLOT_BLOCK) {
        var pcount = previous.getCell().getCount();
        var count = this.getCell().getCount();

        if (_Utility.canMerge(pcount, count)) {
            return SLOT_MERGE;
        }

        return SLOT_BLOCK;
    }
    // if previous state is merge or over
    return SLOT_OVER;
};
Slot.prototype.isEmpty = function () {
    return this.mCell == null;
};
Slot.prototype.draw = function (context) {
    if (this.mCell) {
        this.mCell.draw(context);
    }
};
Slot.prototype.recoverFromLostContext = function (context) {
    if (this.mCell) {
        this.mCell.recoverFromLostContext(context);
    }
};
Slot.prototype.drawMoing = function (direction, context) {
    this.mCell && (this.mPredict[direction] == SLOT_MERGE) && this.mCell.draw(context);
};
/**
 * new cell is turns up on current slot
 * @param predict
 * @param v
 */
Slot.prototype.slideIn = function (predict, v) {
    this.mPosition.add(v, this.mCell.getPosition());
    this.mCell.touchMatrix();
};
/**
 * @param predict gamearea move direction
 * @param v move vector
 */
Slot.prototype.moveCell = function (predict, v) {
    if (!this.mCell) {
        return;
    }
    if (this.mPredict[predict] == SLOT_BLOCK) {
        this.mCell.setPosition(this.mPosition);
    } else {
        this.mPosition.add(v, this.mCell.getPosition());
        this.mCell.touchMatrix();
    }
};
Slot.prototype.getPosition = function () {
    return this.mPosition;
};
Slot.prototype.getCell = function () {
    return this.mCell;
};
Slot.prototype.takeFrom = function (from) {
    this.mCell = from.mCell;
    from.mCell = null;
};
Slot.prototype.releaseCell = function () {
    var c = this.mCell;
    this.mCell = null;
    return c;
};
Slot.prototype.mergeCell = function (from) {
    var mergecount = this.mCell.getCount() + from.mCell.getCount();
    this.mCell.startMerge(mergecount);
    return mergecount;
};
Slot.prototype.bindCell = function (cell) {
    this.mCell = cell;
    if (cell) {
        cell.setPosition(this.mPosition);
    }
};
Slot.prototype.setPredict = function (predict, state) {
    this.mPredict[predict] = state;
};
Slot.prototype.getPredict = function (predict) {
    return this.mPredict[predict];
};
Slot.prototype.predictString = function (direction) {
    var str = '';
    switch (this.mPredict[direction]) {
        case SLOT_BLOCK:
            str = 'X';
            break;
        case SLOT_OVER:
            str = '-';
            break;
        case SLOT_MERGE:
            str = '*';
            break;
    }
    switch (direction) {
        case MOVE_LEFT:
            return '<' + str;
        case MOVE_RIGHT:
            return str + '>';
        case MOVE_TOP:
            return '↑' + str;
        case MOVE_BOTTOM:
            return '↓' + str;
    }
    return '??';
};
Slot.prototype.toString = function (direction) {
    if (this.isEmpty()) {
        return '[* ' + this.predictString(direction) + ']';
    } else {
        return '[' + this.mCell.getCount() + ' ' + this.predictString(direction) + ']';
    }
};

module.exports = Slot;